package com.aptemo.webetek.server.services;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.aptemo.webetek.client.commands.Action;
import com.aptemo.webetek.client.commands.Response;
import com.aptemo.webetek.client.commands.responses.ListResponse;
import com.aptemo.webetek.client.exceptions.BackendException;
import com.aptemo.webetek.client.exceptions.WebetekLoginException;
import com.aptemo.webetek.server.ActionInvoker;
import com.aptemo.webetek.shared.PagingResult;
import com.google.appengine.api.users.UserService;
import com.google.appengine.api.users.UserServiceFactory;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

/**
 * The server side implementation of the Command Service.
 */
public class CommandService
		extends HttpServlet
{

	/**
	 * 
	 */
	private static final long	serialVersionUID	= -2279250563507676273L;

	/**
	 * 
	 */
	private UserService			userService			= UserServiceFactory.getUserService();

	private ActionInvoker		service				= new ActionInvoker();					;

	protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException
	{
		res.setContentType("application/json");
		PrintWriter out = res.getWriter();

		String url = req.getRequestURI().toString();
		String queryString = req.getQueryString();
		if (queryString != null)
		{
			url += "?" + queryString;
		}

		String actionId = req.getParameter("actionId");
		String json = req.getParameter("json");

		// 
		String loginUrl = userService.createLoginURL(url);
		if (!userService.isUserLoggedIn())
		{
			res.sendRedirect(loginUrl);
			return;
		}
		if (!userService.isUserAdmin())
		{
			res.sendRedirect(loginUrl);
			return;
		}

		try
		{
			Gson gson = new GsonBuilder().serializeSpecialFloatingPointValues().setPrettyPrinting().create();
			Action action = (Action) gson.fromJson(json, Class.forName(actionId));

			Object response = service.invoke(action, req);
			if (response instanceof ListResponse<?>)
			{
				ListResponse<?> listres = (ListResponse<?>) response;
				out.println(gson.toJson(listres.getList()));
			}
			else if (response instanceof PagingResult<?>)
			{
				PagingResult<?> pagres = (PagingResult<?>) response;
				out.println(gson.toJson(pagres.getList()));
			}
			else if (response instanceof Response)
			{
				out.println(gson.toJson(response));
			}

		}
		catch (ClassNotFoundException e1)
		{
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		catch (BackendException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		catch (WebetekLoginException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		// TODO....
		// res.sendRedirect("error");
		out.close();
	}
}
